import 'dart:async';

class Synchronized {
  /// 上一个手动异步的future
  Future<dynamic>? _last;

  /// 是否锁住
  bool get locked => _last != null;

  Future<T> run<T>(FutureOr<T> Function() func, {Duration? timeout}) async {
    /// 上一个异步执行future
    final prev = _last;

    /// 开启手动异步
    final completer = Completer.sync();
    _last = completer.future;

    /// 如果上一个future还没有完成就等待完成
    try {
      if (prev != null) {
        timeout != null ? await prev.timeout(timeout) : await prev;
      }
      var result = func();
      return result is Future ? await result : result;
    } finally {
      /// 在超时情况下等待上一个任务完成
      void _complete() {
        // 只有在最后一个完成时才标记为解锁
        if (identical(_last, completer.future)) {
          _last = null;
        }
        completer.complete();
      }

      /// 如果超时，请等待上一个任务也完成，然后再将此任务标记为已完成
      prev != null && timeout != null ? prev.then((_) => _complete()) : _complete();
    }
  }
}
